home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / games / larn12s.arc / LARN.ARC / FORTUNE.C < prev    next >
C/C++ Source or Header  |  1987-10-28  |  3KB  |  130 lines

  1. /* fortune.c         Larn is copyrighted 1986 by Noah Morgan. */
  2. #ifdef GEMDOS
  3. # include <types.h>
  4. # include <stat.h>
  5. # define O_RDONLY 0
  6. #else
  7. # include <sys/types.h>
  8. # include <sys/stat.h>
  9.  
  10. # ifndef BSD4.1
  11. #  include <fcntl.h>
  12. # else BSD4.1
  13. #  define O_RDONLY 0
  14. # endif BSD4.1
  15. #endif GEMDOS
  16.  
  17. #include "header.h"
  18.  
  19. # ifdef MSDOS
  20. # include <stdio.h>
  21. /* Rumors has been entirely rewritten to be disk based.  This is marginally
  22.  * slower, but requires no mallocked memory.  Notice this is only valid for
  23.  * files smaller than 32K.
  24.  */
  25. int    fortsize = 0;
  26.  
  27. outfortune()
  28. {
  29.     int    fd, status, i;
  30.     char    buf[BUFSIZ], ch;
  31.  
  32.     if (fortsize < 0)    /* We couldn't open fortunes */
  33.         return;
  34.     if ((fd = open(fortfile, O_RDONLY | O_BINARY)) >= 0) {
  35.         if (fortsize == 0)
  36.             fortsize = (int) lseek(fd, 0L, 2);
  37.         if (lseek(fd, (long) rund(fortsize), 0) < 0)
  38.             return;
  39.  
  40.         /* Skip to next newline or EOF
  41.          */
  42.         do {
  43.             status = read(fd, &ch, 1);
  44.         } while (status != EOF && ch != '\n');
  45.         if (status == EOF)
  46.             if (lseek(fd, 0L, 0) < 0) /* back to the beginning */
  47.                 return;
  48.  
  49.         /* Read in the line.  Search for CR ('\r'), not NL
  50.          */
  51.         for (i = 0; i < BUFSIZ - 1; i++)
  52.             if (read(fd, &buf[i], 1) == EOF || buf[i] == '\r')
  53.                 break;
  54.         buf[i] = '\0';
  55.  
  56.         /* And spit it out
  57.          */
  58.         lprcat("  Inside you find a scrap of paper that says:\n");
  59.         lprcat(buf);
  60.         close(fd);
  61.     } else
  62.         fortsize = -1;    /* Don't try opening it again */
  63. }
  64.  
  65. # else
  66.  
  67. /*
  68.  *    function to return a random fortune from the fortune file
  69.  */
  70. static char *base=0;    /* pointer to the fortune text */
  71. static char **flines=0;    /* array of pointers to each fortune */
  72. static int fd=0;        /* true if we have load the fortune info */
  73. static int nlines=0;    /* # lines in fortune database */
  74.  
  75. char *fortune(file)
  76. char *file;
  77. {
  78.     register char *p;
  79.     register int lines,tmp,size;
  80.     struct stat fortstat;
  81.     char *malloc();
  82.  
  83.     if (fd == 0) {
  84.         if ((fd=open(file,O_RDONLY)) < 0)    /* open the file */
  85.             return(0); /* can't find file */
  86.  
  87.         /* find out how big fortune file is and get memory for it */
  88.         fortstat.st_size = 16384;
  89.         if ((stat(file,&fortstat) < 0)
  90.         || ((base=malloc(1+(int)fortstat.st_size)) == 0))
  91.             {
  92.             close(fd); fd= -1; free((char*)base); return(0);
  93.              /* can't stat file */
  94.             }
  95.  
  96.         size=(int)fortstat.st_size;
  97.         /* read in the entire fortune file */
  98.         if (read(fd,base,size) != size)
  99.             {
  100.             close(fd); fd= -1; free((char*)base); return(0);     /* can't read file */
  101.             }
  102.         close(fd);  base[size]=0;    /* final NULL termination */
  103.  
  104.         /* count up all the lines (and 0 terminate) to know memory
  105.          * needs
  106.          */
  107.         for (p=base,lines=0; p<base+size; p++) /* count lines */
  108.             if (*p == '\n') *p=0,lines++;
  109.         nlines = lines;
  110.  
  111.         /* get memory for array of pointers to each fortune */
  112.         if ((flines=(char**)malloc(nlines*sizeof(char*))) == 0)
  113.             {
  114.             free((char*)base); fd= -1; return(0); /* malloc() failure */
  115.             }
  116.  
  117.         /* now assign each pointer to a line */
  118.         for (p=base,tmp=0; tmp<nlines; tmp++)
  119.             {
  120.             flines[tmp]=p;  while (*p++); /* advance to next line */
  121.             }
  122.     }
  123.  
  124.     if (fd > 2)    /* if we have a database to look at */
  125.         return(flines[rund((nlines<=0)?1:nlines)]);
  126.     else 
  127.         return(0);
  128. }
  129. # endif
  130.